package com.cskaoyan.user.service.impl;

import com.cskaoyan.mall.commons.exception.ExceptionProcessorUtils;
import com.cskaoyan.mall.commons.util.jwt.AESUtil;
import com.cskaoyan.user.constants.UserRetCode;
import com.cskaoyan.user.converter.MemberConverter;
import com.cskaoyan.user.dal.entitys.Member;
import com.cskaoyan.user.dal.entitys.UserVerify;
import com.cskaoyan.user.dal.persistence.MemberMapper;
import com.cskaoyan.user.dal.persistence.UserVerifyMapper;
import com.cskaoyan.user.dto.UserRegisterResponse;
import com.cskaoyan.user.form.UserRegisterRequest;
import com.cskaoyan.user.form.UserVerifyRequest;
import com.cskaoyan.user.service.IUserRegisterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @Date 2022-12-03 10:46
 * @Created by yepq2025@outlook.com
 */
@Service
@Transactional
public class IUserRegisterServiceImpl implements IUserRegisterService {
    @Autowired
    MemberMapper memberMapper;

    @Autowired
    UserVerifyMapper userVerifyMapper;

    @Autowired
    MemberConverter memberConverter;

    @Autowired
    MailSender mailSender;

    public static final String username1 = "^(\\w){3,10}$";
    public static final String password1 = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$";


    @Override
    public UserRegisterResponse register(UserRegisterRequest request) {
        UserRegisterResponse response = new UserRegisterResponse ( );
        try {
            // 对参数进行校验
            request.requestCheck ();
            Member member = memberConverter.UserLoginRequestToMember ( request );
            // 1、 首先进行正则校验

            // 1.1 对账号进行正则校验
            // 正则，匹配字符数字，且长度在3-10之间
            String memberUsername = member.getUsername ( );
            boolean flag = memberUsername.matches ( username1 );
            if (!flag) {
                response.setCode ( UserRetCode.REQUEST_FORMAT_ILLEGAL.getCode () );
                response.setMsg ( UserRetCode.REQUEST_FORMAT_ILLEGAL.getMessage () );
                return response;
            }
            // 1.2 对密码进行正则校验
            // 正则，判断长度大于8位再接着判断是否包含数字和字符
            String password = member.getPassword ( );
            boolean flag1 = password.matches ( password1 );
            if (!flag1) {
                response.setCode ( UserRetCode.REQUEST_FORMAT_ILLEGAL.getCode () );
                response.setMsg ( UserRetCode.REQUEST_FORMAT_ILLEGAL.getMessage () );
                return response;
            }

            // 2、对注册信息进行校验，判断username, email是否唯一
            Example example = new Example ( Member.class );
            example.createCriteria ().orEqualTo ( "username", member.getUsername () )
                                     .orEqualTo ( "email", member.getEmail () );
            List<Member> members = memberMapper.selectByExample ( example );
            if (members.size () != 0) {
                response.setCode ( UserRetCode.USERNAME_ALREADY_EXISTS.getCode () );
                response.setMsg ( UserRetCode.USERNAME_ALREADY_EXISTS.getMessage () );
                return response;
            }
            // 3、往member表里插入数据
            Date date = new Date ( );
            member.setCreated ( date );
            member.setUpdated ( date );
            // 3.1 对密码加密后插入
            AESUtil aesUtil = new AESUtil ( password );
            String encrypt = aesUtil.encrypt ( );
            member.setPassword ( encrypt );
            int i = memberMapper.insertSelective ( member );

            // 4、往userVerify表里插入数据
            UserVerify userVerify = new UserVerify ( );
            userVerify.setUsername ( member.getUsername () );
            String key = member.getUsername () + member.getPassword () + UUID.randomUUID ().toString ();
            String uuid = DigestUtils.md5DigestAsHex ( key.getBytes ( ) );
            userVerify.setUuid ( uuid );
            userVerify.setRegisterDate ( new Date (  ) );
            userVerify.setIsExpire ( "N" );
            userVerify.setIsVerify ( "N" );
            int num = userVerifyMapper.insertSelective ( userVerify );

            // 5、邮箱发送邮件
            sendMail(uuid, request);
            response.setCode ( UserRetCode.SUCCESS.getCode () );
            response.setMsg ( UserRetCode.SUCCESS.getMessage () );
        } catch (Exception e) {
            e.printStackTrace ();
            ExceptionProcessorUtils.wrapperHandlerException ( response, e );
        }
        return response;
    }

    /**
     * TODO: 发送邮件的方法
     * author: yepq2025@outlook.com
     * time: 2022-12-03 11:22:13
    */
    private void sendMail(String uuid, UserRegisterRequest request) {
        SimpleMailMessage message = new SimpleMailMessage ( );
        message.setSubject ( "CSMALL激活" );
        message.setFrom ( "kerbaluiz@163.com" );
        message.setTo ( request.getEmail () );
        StringBuilder stringBuilder = new StringBuilder ( );
        stringBuilder.append("http://localhost:8099/user/verify?uuid=").append(uuid).append("&username=").append(request.getUserName());
        message.setText ( stringBuilder.toString () );
        mailSender.send ( message );

    }

}
